/* 
    双向链表
*/
let { Node, defaultEquals, LinkedList } = require("./6_1");

class DoublyNode extends Node {
  //  节点类
  constructor(element, prev, next) {
    super(element, next);
    this.prev = prev;
  }
}

// 链表类
class DoublyLinkedList extends LinkedList {
  constructor(equalsFn = defaultEquals) {
    super(equalsFn);
    this.tail = null;
  }

  // 在任意位置插入新元素
  insert(element, index) {
    if (index >= 0 && index <= this.count) {
      // 位置合法
      let node = new DoublyNode(element);
      let current = this.head;
      if (index === 0) {
        // 首部
        if (this.head === null) {
          this.head = node;
          this.tail = node;
        } else {
          node.next = this.head;
          current.prev = node;
          this.head = node;
        }
      } else if (index === this.count) {
        // 尾部
        current = this.tail;
        current.next = node;
        node.prev = current;
        this.tail = node;
      } else {
        // 中间
        let previous = this.getElementAt(index - 1);
        current = previous.next;
        previous.next = node;
        node.prev = previous;
        current.prev = node;
        node.next = current;
      }
      this.count++;
      return true;
    }
    //位置非法
    return false;
  }

  // 删除任意位置元素
  removeAt(index) {
    if (index >= 0 && index <= this.count) {
      // 合法性判断
      let current = this.head; // 块作用域，方便返回结果
      if (index === 0) {
        // 队首元素
        this.head = current.next;
        if (this.count === 1) {
          // 只有一个元素
          this.tail = undefined;
        } else {
          // 多个元素
          this.head.prev = undefined;
        }
      } else if (index === this.count) {
        // 队尾
        current = this.tail;
        this.tail = current.prev;
        current.prev.next = undefined;
      } else {
        // 处理中间位置
        let previous = this.getElementAt(index - 1);
        let current = previous.next;

        previous.next = current.next;
        current.next.prev = previous;
      }
      this.count--;
      return this.current.element;
    }
    return undefined;
  }
}

module.exports = {
  DoublyLinkedList: DoublyLinkedList,
};
